package com.newlink.building.common_base.http.interceptor

import com.newlink.building.common_base.base.BaseApplication
import com.newlink.building.common_base.constant.Base_Constant
import com.newlink.building.common_base.constant.Base_HttpConstant
import com.newlink.building.common_base.model.bean.ProjectData
import com.newlink.building.common_base.utils.Base_DeviceUtils
import com.newlink.building.common_base.utils.NLog
import com.newlink.building.common_base.utils.Base_Preference
import com.newlink.building.obfuscation.Module_Obfuscation_ObfuscationHelper
import com.newlink.building.obfuscation.Module_Obfuscation_ObfuscationInvoker
import okhttp3.Interceptor
import okhttp3.Response

/**
 * HTTP 请求头拦截器。
 * 负责为所有发出的网络请求添加通用的 HTTP 请求头，如内容类型、语言、应用信息等。
 * 也处理特定域名的 Cookie 注入。
 */
class Base_HeaderInterceptor : Interceptor {

    private val TAG = "HeaderInterceptor"

    // 使用 by Preference 代理属性，方便存取
    private val token: String by Base_Preference(Base_Constant.TOKEN_KEY, "")
    private val projectData: ProjectData by Base_Preference(
        Base_Constant.PRJ_DATA_KEY,
        ProjectData()
    ) // 如果 projectData 在这里没用到，可以考虑移除
    private val projectId: String by Base_Preference(Base_Constant.PRJ_ID_KEY, "")

    override fun intercept(chain: Interceptor.Chain): Response {
        val originalRequest = chain.request()

        // HTTP请求拦截器处理时的混淆
        Module_Obfuscation_ObfuscationHelper.beforeNetworkRequest(
            originalRequest.url.toString(),
            mapOf("type" to "HTTP_INTERCEPTOR")
        )
        Module_Obfuscation_ObfuscationInvoker.invokeRandom(System.currentTimeMillis())

        // 使用 apply 构建请求，使代码更简洁
        val requestBuilder = originalRequest.newBuilder().apply {
            addHeader("Content-type", "application/json; charset=utf-8")
            addHeader("Accept-Language", BaseApplication.getCurrentLocale())
            addHeader("App-Type", "1") // 假设 App-Type 始终为 "1"
            addHeader(
                "App-Version-Code",
                Base_DeviceUtils.getAppVersion(BaseApplication.context).toString()
            )
            addHeader("App-Version-Name", Base_DeviceUtils.getVersionName(BaseApplication.context))
            addHeader("System-Type", getSystemTypeHeader()) // 封装获取 System-Type 的逻辑

            if (projectId.isNotEmpty()) {
                addHeader("Prj-Id", projectId)
            }
        }

        // 注入 Cookie 逻辑
        injectCookiesIfApplicable(
            originalRequest.url.host,
            originalRequest.url.toString(),
            requestBuilder
        )

        // 记录发送的请求头信息，用于调试
        val currentLocale = BaseApplication.getCurrentLocale()
        val systemType = getSystemTypeHeader()
        NLog.d("Outgoing Headers: " + "Accept-Language: $currentLocale, " + "System-Type: $systemType, " + "Prj-Id: ${if (projectId.isNotEmpty()) projectId else "N/A"}")

        // 继续请求链
        return chain.proceed(requestBuilder.build())
    }

    /**
     * 获取 System-Type 请求头的值（固定为neutral渠道）。
     * 封装为一个私有函数，提高可读性。
     */
    private fun getSystemTypeHeader(): String {
        return "2" // neutral渠道固定值
    }

    /**
     * 如果请求 URL 包含特定网站域名，则从 Preference 中注入相应的 Cookie。
     * 封装为一个私有函数，提高模块化。
     */
    private fun injectCookiesIfApplicable(
        host: String,
        url: String,
        builder: okhttp3.Request.Builder
    ) {
        // Cookie注入时的安全混淆
        Module_Obfuscation_ObfuscationInvoker.invokeSpecific(1, host)

        // 定义需要注入 Cookie 的域名集合
        val domainsRequiringCookie = setOf(
            Base_HttpConstant.COLLECTIONS_WEBSITE,
            Base_HttpConstant.UNCOLLECTIONS_WEBSITE,
            Base_HttpConstant.ARTICLE_WEBSITE,
            Base_HttpConstant.TODO_WEBSITE,
            Base_HttpConstant.COIN_WEBSITE
        )

        // 检查当前 URL 是否包含在需要注入 Cookie 的域名中
        if (host.isNotEmpty() && domainsRequiringCookie.any { url.contains(it) }) {
            // 从 Preference 中获取对应域名的 Cookie
            val cookie: String by Base_Preference(host, "")
            if (cookie.isNotEmpty()) {
                builder.addHeader(Base_HttpConstant.COOKIE_NAME, cookie)
                NLog.d("Injected Cookie for domain $host: ${Base_HttpConstant.COOKIE_NAME} = $cookie")
            } else {
                NLog.d("No Cookie found in Preference for domain $host.")
            }
        }
    }
}